import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ConcurrentTCPSPellingServer extends AbstractServer
{

	private ServerSocket tcpServerSocket;
	private int threadcount = 1;
	private ExecutorService thread_pool;

	public ConcurrentTCPSPellingServer(String[] the_args, int number)
			throws SocketException
	{
		super(the_args);
		Log.out("Configuring for the No." + number + "sessions");
		this.thread_pool = Executors.newFixedThreadPool(number);
	}

	public void excute() throws IOException
	{
		Socket accpetSocket = this.tcpServerSocket.accept();
		int tempcount = adjustcount();
		Log.out("Enqueued connection from " + accpetSocket.getInetAddress()
				+ " to " + accpetSocket.getPort() + " as session " + tempcount);
		this.thread_pool.submit(new TCPSpellingServer(this, tempcount, accpetSocket));
	}

	private synchronized int adjustcount()
	{
		return this.threadcount++;
	}

	public static String[] adjustarray(String[] the_args)
	{
		String[] temp = new String[2];
		temp[0] = the_args[0];
		temp[1] = the_args[1];
		return temp;
	}

	public static int findthreadnumber(String[] args)
	{
		int num = 10;
		if (args.length > 2)
		{
			try
			{
				num = Integer.parseInt(args[2]);
			} catch (NumberFormatException e)
			{
				num = 10;
			}
		}
		return num;
	}

	public static void main(String[] args) throws SocketException
	{
		int num_threads = findthreadnumber(args);
		args = adjustarray(args);
		ConcurrentTCPSPellingServer server = new ConcurrentTCPSPellingServer(
				args, num_threads);
		try
		{
			server.tcpServerSocket = new ServerSocket(server.my_port);
			Log.out("Open on port " + server.tcpServerSocket.getLocalPort());
			Log.out("Initialized network. Ready for queries.");
		} catch (IOException e)
		{
			Log.err("Cannot initialize networks " + e);
			e.printStackTrace();
		}

		for (;;)
		{
			try
			{
				server.excute();
			}
			// catch (InterruptedException e)
			// {
			// Log.err("Timed out. " + e);
			// e.printStackTrace();
			// }
			catch (IOException e)
			{
				Log.err("IO problem: " + e.getClass().getName());
				e.printStackTrace();
			}
		}
	}

}
